package com.example.newfolder.Controller;

import com.Auth.AuthCodeSender;
import com.alibaba.fastjson.JSONObject;
import com.http.BaiduOAuthConfig;
import com.http.BaiduPanConfig;
import com.util.Folders;
import com.util.SQLHelp;
import com.util.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
public class UserController {

    @RequestMapping("login")
    public String login(@CookieValue(value = "token", defaultValue = "token") String token) throws UnsupportedEncodingException {
        if(token.equals("token")){
            return "redirect:/toLogin";
        }
        token = URLDecoder.decode(token, "utf-8");
        String[] u = token.split(";");
        if(u.length != 2){
            return "redirect:/toLogin";
        }
        String userName = u[0];
        String password = u[1];
        if(User.checkPassword(userName, password)){
            return "redirect:/index";
        }else{
            return "redirect:/toLogin";
        }
    }

    @RequestMapping("/toLogin")
    public ModelAndView toLogin(){
        ModelAndView modelAndView = new ModelAndView("login");
        modelAndView.addObject("user", new User());
        return modelAndView;
    }

    @ResponseBody
    @RequestMapping("/check_name")
    public JSONObject checkName(@RequestParam (value = "name")String name){
        JSONObject json = new JSONObject();
        if(User.isExistName(name)){
            json.put("res",0);
        }else{
            json.put("res",1);
        }
        return json;
    }

    @RequestMapping("/register")
    public String register(@ModelAttribute User user, HttpServletResponse response) throws UnsupportedEncodingException {
        int res = User.insertUser(user.getUserName(), user.getEmail(), user.getPassword());
        if(res == 1){
            String tokenValue = String.format("%s;%s", user.getUserName(), user.getPassword());
            tokenValue = URLEncoder.encode(tokenValue, "utf-8");
            Cookie c = new Cookie("token", tokenValue);
            if(user.getRemember()){
                // cookie time
                c.setMaxAge(7 * 24 * 60 * 60);
            }else{
                // delete when close
                c.setMaxAge(-1);
            }
            response.addCookie(c);
            c = new Cookie("userId", user.getUserId().toString());
            if(user.getRemember()){
                // cookie time
                c.setMaxAge(7 * 24 * 60 * 60);
            }else{
                // delete when close
                c.setMaxAge(-1);
            }
            response.addCookie(c);
            return "redirect:/index";
        }else{
            return "redirect:/login";
        }
    }

    @PostMapping("/check_password")
    public String checkPassword(@ModelAttribute User user, HttpServletResponse response) throws UnsupportedEncodingException {
        if(User.checkPassword(user.getUserName(), user.getPassword())){
            String tokenValue = String.format("%s;%s", user.getUserName(), user.getPassword());
            tokenValue = URLEncoder.encode(tokenValue, "utf-8");
            Cookie c = new Cookie("token", tokenValue);
            if(user.getRemember()){
                // cookie time
                c.setMaxAge(7 * 24 * 60 * 60);
            }else{
                // delete when close
                c.setMaxAge(-1);
            }
            response.addCookie(c);
            c = new Cookie("userId", user.getUserId().toString());
            if(user.getRemember()){
                // cookie time
                c.setMaxAge(7 * 24 * 60 * 60);
            }else{
                // delete when close
                c.setMaxAge(-1);
            }
            response.addCookie(c);
            return "redirect:/index";
        }return "redirect:/login";
    }

    @ResponseBody
    @RequestMapping("/check_password2")
    public JSONObject checkUserPassword(@RequestParam (value = "user") String user,@RequestParam (value = "password") String password){
        JSONObject jsonObject = new JSONObject();
        if (User.checkPassword(user,password)){
            jsonObject.put("res",200);
        }else{
            jsonObject.put("res",0);
        }
        return jsonObject;
    }

    @RequestMapping("/index")
    public String index(@CookieValue(value = "token", defaultValue = "token") String token,
                        @ModelAttribute(value = "userFolderView")UserFolderView userFolderView,
                        @CookieValue(value = "userId", defaultValue = "0") String userId,
                        HttpServletRequest request) throws IOException {
        String type = request.getParameter("sort_type");
        String search = request.getParameter("search");
        String page = request.getParameter("page");
        Integer pageIndex = 0;
        if (page != null){
            pageIndex = Integer.parseInt(page);
        }
        if (type == null){
            type ="";
        }
        if (search == null){
            search ="";
        }
        if (token.equals("token")) {
            return "redirect:/login";
        }
        HashMap<String, Integer> numsMap = BaiduPanConfig.getFileListAll(userId);
        userFolderView.setNumsMap(numsMap);
        if (type.equals("create")) {
            userFolderView.setFolderList(Folders.sortByCreateTime(userId,search));
        } else if (type.equals("stop")) {
            userFolderView.setFolderList(Folders.sortByStopTime(userId,search));
        } else if (type.equals("star")) {
            userFolderView.setFolderList(Folders.isStar(userId,search));
        }else if(type.equals("nums")){
            ArrayList<HashMap<String, String>> folderList = User.folderList(userId,search);
            folderList.sort(new Comparator<HashMap<String, String>>() {
                @Override
                public int compare(HashMap<String, String> o1, HashMap<String, String> o2) {
                    String k1 = o1.get("folder_key");
                    String k2 = o2.get("folder_key");
                    Integer n1 = numsMap.get(k1);
                    Integer n2 = numsMap.get(k2);
                    if(n1 == null){
                        n1 = 0;
                    }
                    if(n2 == null){
                        n2 = 0;
                    }
                    return n2 - n1;
                }
            });
            userFolderView.setFolderList(folderList);
        }
        else {
            userFolderView.setFolderList(User.folderList(userId,search));
        }
        userFolderView.autoPage(pageIndex);
        userFolderView.setType(type);
        return "index";
    }

    @RequestMapping("/driver")
    public String driver(@CookieValue(value = "token", defaultValue = "token") String token){
        if(token.equals("token")){
            return "redirect:/login";
        }
        return "driver";
    }
    @ResponseBody
    @RequestMapping("/get_all_driver")
    public JSONObject getUserPanList(@CookieValue(value = "userId", defaultValue = "0") String userId) throws IOException {
        Integer u = Integer.parseInt(userId);
        JSONObject r = new JSONObject();
        if(u == 0){
            r.put("res", "user_error");
            return new JSONObject();
        }
        User user = new User(u);
        Integer i = 0;
        for (HashMap<String, String> h :
                user.getPanList()) {
            String accessToken = h.get("access_token");
            accessToken = BaiduOAuthConfig.checkAndGetPanAccessToken(accessToken);
            if(accessToken.equals("")){
                continue;
            }
            JSONObject o = BaiduOAuthConfig.getUserInfo(accessToken);
            if(o.get("errno") == null || o.get("errno").equals(0)){
                r.put(i.toString(), o);
                i++;
            }
        }
        r.put("res", "suc");
        r.put("pan_count", i);
        return r;
    }

    @RequestMapping("/add_folder")
    public String addFolder(@RequestParam(value = "index") Integer index, @CookieValue(value = "userId", defaultValue = "0") String userId){
        Integer u = Integer.parseInt(userId);
        if(u == 0){
            return "redirect:/login";
        }
        return "addFolder";
    }

    @ResponseBody
    @RequestMapping("/add_folder_submit")
    public JSONObject addFolderSubmit(HttpServletRequest request, @CookieValue(value = "userId", defaultValue = "0") String userId){
        Integer u = Integer.parseInt(userId);
        JSONObject jsonObject = new JSONObject();
        if(u == 0){
            jsonObject.put("res", "user_error");
            return jsonObject;
        }
        String folderName = request.getParameter("name"),
                desc = request.getParameter("describe"),
                firstName = "",
                secondName = "",
                thirdName = "",
                stopSeconds = request.getParameter("datetime");
        if(request.getParameter("one").equals("true")){
            firstName = request.getParameter("first");
        }
        if(request.getParameter("two").equals("true")){
            secondName = request.getParameter("second");
        }
        if(request.getParameter("three").equals("true")){
            thirdName = "1";
        }else{
            thirdName = "0";
        }
        String panIndex = request.getParameter("panIndex");
        Integer p = Integer.parseInt(panIndex);
        Integer panId = u * 10 + p;
        try{
            String folderKey = Folders.saveFolder(folderName, desc, firstName, secondName, thirdName, stopSeconds, panId.toString(), userId);
            if(folderKey.equals("")){
                jsonObject.put("res", "save_error");
            }else{
                jsonObject.put("suc", folderKey);
            }
        }catch (Exception e){
            jsonObject.put("res", "save_error");
        }
        return jsonObject;
    }

    @ResponseBody
    @RequestMapping("/get_all_folder")
    public JSONObject getAllFolder(@CookieValue("userId") String userId){
        Integer u = Integer.parseInt(userId);
        JSONObject jsonObject = new JSONObject();
        if(u == 0){
            jsonObject.put("res", "user_error");
            return jsonObject;
        }
        String sqlFormat = "select * from folder where user_id = %s";
        String sql = String.format(sqlFormat, userId);
        ArrayList<HashMap<String, String>> result = SQLHelp.selectQuery(sql);
        Integer index = 0;
        for (HashMap<String, String> h:
        result){
            jsonObject.put(String.valueOf(index++), h);
        }
        jsonObject.put("folder_count", index);
        jsonObject.put("res", "suc");
        return jsonObject;

    }

    @RequestMapping("/exit")
    public String exit(HttpServletResponse response){
        Cookie c = new Cookie("token", null);
        c.setMaxAge(0);
        response.addCookie(c);
        c = new Cookie("userId", null);
        c.setMaxAge(0);
        response.addCookie(c);
        return "redirect:/login";
    }

    @ResponseBody
    @RequestMapping("/send_code")
    public JSONObject sendEmail(@RequestParam(value = "email")String email){
        AuthCodeSender.sendAuthCodeMail(email);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("res", 200);
        return jsonObject;
    }

    @ResponseBody
    @RequestMapping("/check_code")
    public JSONObject checkCode(@RequestParam(value = "code")Integer code,@RequestParam(value = "email")String email){
        boolean b = AuthCodeSender.vertifyAuthCode(email, code);
        JSONObject jsonObject = new JSONObject();
        if(b){
            jsonObject.put("res",200);
        }else{
            jsonObject.put("res",0);
        }
        return jsonObject;
    }

    @ResponseBody
    @RequestMapping("/change_star")
    public void changeFolderStar(@RequestParam(value = "key")String key,@RequestParam(value = "value")String value){
        User.changeStar(key,value);
    }

    @ResponseBody
    @RequestMapping("/change_open")
    public void changeFolderOpen(@RequestParam(value = "key")String key,@RequestParam(value = "value")String value){
        User.changeOpen(key,value);
    }

    @ResponseBody
    @RequestMapping("/delete_folder")
    public void deleteFolder(@RequestParam(value = "key")String key){
        Folders.deleteFolder(key);
    }
    @ResponseBody
    @RequestMapping("/change_deadline")
    public void changeDeadline(@RequestParam(value = "key")String key,
                               @RequestParam(value = "datetime")String datetime){
        Folders.changeDeadline(key,datetime);
    }

    @RequestMapping("/to_change_password")
    public ModelAndView toChangePassword(){
        ModelAndView modelAndView = new ModelAndView("changePassword");
        modelAndView.addObject("user", new User());
        return modelAndView;
    }

    @RequestMapping("/change_password")
    public String changePassword(@ModelAttribute User user){
        User.changePassword(user.userName,user.password);
        return "redirect:/exit";
    }


    @ResponseBody
    @RequestMapping("/send_code_to_change_psw")
    public JSONObject sendCode(@RequestParam(value = "name")String name){
        String email = User.getEmailByName(name);
        JSONObject jsonObject = new JSONObject();
        if (email.equals("")) {
            jsonObject.put("res",0);
        }else {
            AuthCodeSender.sendAuthCodeMail(email);
            jsonObject.put("res", 200);
        }
        return jsonObject;
    }

    @ResponseBody
    @RequestMapping("/check_code_by_name")
    public JSONObject checkCodeByName(@RequestParam(value = "code")Integer code,@RequestParam(value = "name")String name){
        String email = User.getEmailByName(name);
        JSONObject jsonObject = new JSONObject();
        boolean b = AuthCodeSender.vertifyAuthCode(email, code);
        if(b){
            jsonObject.put("res",200);
        }else{
            jsonObject.put("res",0);
        }
        return jsonObject;
    }

    @RequestMapping("/share_link")
    public ModelAndView shareLink(@RequestParam("folder_key")String folderKey){
        return new ModelAndView("share_link");
    }

}

class FolderView{
    public String folderName;
    public String folderKey;
    public int openFlag;
    public int starFlag;
    public String folderDeadline;

    public String describe;

    public boolean overdue;

    public HashMap<String, Integer> numsMap;


    public FolderView(){}

    public FolderView(HashMap<String,String> hashMap, HashMap<String, Integer> numsMap){
        folderName = hashMap.get("folder_name");
        folderKey = hashMap.get("folder_key");
        openFlag = Integer.parseInt(hashMap.get("folder_open"));
        starFlag = Integer.parseInt(hashMap.get("star"));
        long fileTime = Long.parseLong(hashMap.get("stop_seconds"));
        Date deadline = new Date(Long.parseLong(hashMap.get("stop_seconds"))*1000);
        String pattern = "yyyy-MM-dd HH:mm";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        folderDeadline=simpleDateFormat.format(deadline);
        describe = hashMap.get("folder_describe");
        long date = System.currentTimeMillis()/1000;
        if (date > fileTime){
            overdue = true;
        }else{
            overdue = false;
        }
        this.numsMap = numsMap;
    }

    public int getFileNums(){
        if (!numsMap.containsKey(folderKey)) {
            return 0;
        }
        return numsMap.get(folderKey);
    }

    public void setFolderView(HashMap<String,String> hashMap){
        folderName = hashMap.get("folder_name");
        folderKey = hashMap.get("folder_key");
        openFlag = Integer.parseInt(hashMap.get("folder_open"));
        starFlag = Integer.parseInt(hashMap.get("star"));
        long fileTime = Long.parseLong(hashMap.get("stop_seconds"));
        Date deadline = new Date(fileTime*1000);
        String pattern = "yyyy-MM-dd HH:mm";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);
        long date = System.currentTimeMillis()/1000;
        if (date > fileTime){
            overdue = true;
        }else{
            overdue = false;
        }
        folderDeadline=simpleDateFormat.format(deadline);
        describe = hashMap.get("folder_describe");
        this.numsMap = numsMap;
    }
}

class UserFolderView{
    public ArrayList<FolderView> folderList;
    public int size;
    public int page;
    public String type;

    public static int pageSize=7;

    public HashMap<String, Integer> numsMap = new HashMap<>();

    public UserFolderView(){

    }

    public void setNumsMap(HashMap<String, Integer> numsMap){
        this.numsMap = numsMap;
    }

    public void setFolderList(ArrayList<HashMap<String, String>> _folderList){
        folderList = new ArrayList<>();
        for (HashMap<String,String> hashMap:_folderList){
            folderList.add(new FolderView(hashMap, numsMap));
        }
        size=(int)Math.ceil(folderList.size()*1.0/pageSize);
        page = 0;
        if (size <= 0){
            size = 1;
        }
    }

    public void autoPage(int page){
        int start = pageSize*page;
        int end = start+pageSize;
        ArrayList<FolderView> list = new ArrayList<>();
        for (int i = start; i < end; ++i){
            if (folderList.size()<=i){
                break;
            }
            list.add(folderList.get(i));
        }
        folderList = list;
        this.page = page;
    }

    public HashMap<String,String> getTypeMap(){
        HashMap<String,String> has = new HashMap<>();
        has.put("create","创建时间");
        has.put("stop","截止时间");
        has.put("star","只显示星");
        has.put("nums", "收件数量");
        has.put("","创建时间");
        return has;
    }

    public String getType(){
        return getTypeMap().get(type).toString();
    }

    public void setType(String type){
        this.type = type;
    }
}

